package org.qtproject.example.NovaUI;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Handler;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;

import java.io.File;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;

import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.offline.OfflineMessageManager;

import java.util.HashMap;
import java.util.List;

public class MyService extends Service {
    AbstractXMPPConnection connection;

    private Handler handler;
    private NotificationManager mNM;

    private static final String BROADCAST_ACTION = "org.qtproject.example.NovaUI.MainActivity";
    private int NOTIFICATION = 1;
    private long[] vibratePattern = {0,1000};

    private HashMap<String, Chat> chats = new HashMap<String, Chat>();


    @Override
    public void onCreate() {
        super.onCreate();

        handler = new Handler();
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
//                    xmppInit("acessetec1", "acessetec123", "talk.google.com", 5222, "gmail.com");
                    while(!xmppInit("acessetec2", "acessetec123", "talk.google.com", 5222, "gmail.com")) {
                        try {
                            Thread.sleep(10000);
                        } catch(Exception ex) {}
                    }

                    monitoreMessages();
                }
            }
        });
        t.start();

    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    private void runOnUiThread(Runnable runnable) {
        handler.post(runnable);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
//        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
    }

    private void persistNotification(String sender, String message) {
        String textString = sender+":"+message;
        try {
//            File file = new File(this.getFilesDir(), "notification"+System.currentTimeMillis()+".xmpp");
            File file = new File(this.getCacheDir(), "notification"+System.currentTimeMillis()+".xmpp");

            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));

            out.write(textString.getBytes());
            out.close();
            Thread.sleep(1);
        } catch (Exception e) {}
    }

    private String readNotifications() {
        File dir = this.getCacheDir();
        String result = "";

        for (final File fileEntry : dir.listFiles()) {
            if(!fileEntry.getPath().endsWith(".xmpp"))  continue;

            try {
                BufferedReader br = new BufferedReader(new FileReader(fileEntry));
                String line;
                while ((line = br.readLine()) != null) {
                   result += line + "\r\n";
                }
                br.close();
            } catch(Exception e){}
        }


        return result;
    }

    private void monitoreMessages() {
        String lastMsgs = "";
        while(connection.isConnected()) {
            String currMsgs = readNotifications();
            if(lastMsgs.equals(currMsgs)) {
                try{Thread.sleep(1000);} catch(Exception e){}
                continue;
            }

            try{Thread.sleep(3000);} catch(Exception e){}
            String newMsgs = readNotifications();
            if(newMsgs.contains(currMsgs)) {
                showNotifications();
                lastMsgs = newMsgs;
            } else {
                mNM.cancel(NOTIFICATION);
                lastMsgs = "";
            }
        }
    }


    private boolean xmppInit(final String user, final String passwd, final String server, final int port, final String domain) {
        ConnectionConfiguration connConfig = new ConnectionConfiguration(server, port, domain);

        connection = new XMPPTCPConnection(connConfig);

        try {
            connection.connect();

/*
            PacketFilter myFilter = new PacketFilter() {
                public boolean accept(Packet packet) {
                    return true;
                }
            };

            PacketListener myListener = new PacketListener() {
                public void processPacket(Packet packet) {
                    String from = packet.getFrom();
                    persistNotification("Teste", packet.toXML().toString());
                }
            };
            connection.addPacketListener(myListener,myFilter);
*/

            connection.login(user, passwd);

/*
            try {
                ServiceDiscoveryManager manager = ServiceDiscoveryManager.getInstanceFor(connection);

                OfflineMessageManager omm = new OfflineMessageManager(connection);
                List<Message> messages = omm.getMessages();

                for(Message m: messages) {
                    persistNotification("OFF:", m.getFrom());
                }
            } catch(Throwable e) {
                persistNotification("EX:", e.getMessage());
            }
*/

/*
            Presence presence = new Presence(Presence.Type.unavailable);
            presence.setStatus("I’m unavailable");
            connection.sendPacket(presence);
*/

            Presence presence = new Presence(Presence.Type.available);
            presence.setStatus("I’m available");
            connection.sendPacket(presence);

            final ChatManager cm = ChatManager.getInstanceFor(connection);

            final MessageListener messageListener = new MessageListener() {
                public void processMessage(Chat chat, Message message) {
                    if(message.getBody()!=null) {
                        try {
                            chat.sendMessage(chat.getParticipant()+": "+message.getBody());
                        } catch(Exception e) {}

                        persistNotification(chat.getParticipant(), message.getBody());
                    }
                }
            };

            cm.addChatListener(new ChatManagerListener() {
                public void chatCreated(Chat chat, boolean createdLocally) {
                    if(!createdLocally) {
                        chat.addMessageListener(messageListener);
                        chats.put(chat.getParticipant(), chat);
                    }
                }
            });
        } catch (Exception e) {
            return false;
        }

/*
        } catch (SmackException e1) {
//        } catch (NotConnectedException e2) {
        } catch (IOException e3) {
        } catch (XMPPException e4) {
            connection = null;
            //Unable to connect to server
        }
*/

        return true;
    }


    private void showNotifications() {
        String titleString = "Preço Líder:";

        String notificationsText = readNotifications();

        if(notificationsText.isEmpty()) {
            mNM.cancel(NOTIFICATION);
            return;
        }

/*
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
             new Intent(this, MainActivity.class), 0);
*/
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
             new Intent(this, org.qtproject.qt5.android.bindings.QtActivity.class), 0);

/*
        @SuppressWarnings("deprecation")
        Notification notification = new Notification(android.R.drawable.ic_menu_add, textString, System.currentTimeMillis());
        notification.setLatestEventInfo(this, titleString, textString, contentIntent);
*/
        Notification notification = new Notification.Builder(this)
        .setContentTitle(titleString)
//        .setContentText(notificationsText)
        .setStyle(new Notification.BigTextStyle().bigText(notificationsText))
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setAutoCancel(true)
        .setContentIntent(contentIntent)
        .setVibrate(vibratePattern)
        .build();

        mNM.notify(NOTIFICATION, notification);
     }
}
